Initial commit at Tue Apr 25 08:41:48 EDT 2017 by tim on stravinsky

This commit is contained in:
Tim Edwards
2017-04-25 08:41:48 -04:00
commit 231a299b16
1249 changed files with 520134 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
lefCmd.o: lefCmd.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../windows/windows.h ../dbwind/dbwind.h \
../utils/main.h ../textio/txcommands.h ../commands/commands.h
lefTech.o: lefTech.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../utils/malloc.h ../lef/lefInt.h ../drc/drc.h
lefWrite.o: lefWrite.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../utils/tech.h ../utils/utils.h \
../utils/malloc.h ../utils/stack.h ../utils/signals.h \
../windows/windows.h ../dbwind/dbwind.h ../graphics/graphics.h \
../utils/main.h ../utils/undo.h ../cif/cif.h ../lef/lefInt.h
defWrite.o: defWrite.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../utils/tech.h ../utils/malloc.h ../utils/undo.h \
../cif/cif.h ../extflat/extflat.h ../lef/lefInt.h ../drc/drc.h
lefRead.o: lefRead.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \
../database/database.h ../windows/windows.h ../graphics/graphics.h \
../dbwind/dbwind.h ../utils/malloc.h ../textio/textio.h ../cif/cif.h \
../cif/CIFint.h ../lef/lefInt.h
defRead.o: defRead.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \
../database/database.h ../windows/windows.h ../dbwind/dbwind.h \
../utils/malloc.h ../graphics/graphics.h ../utils/main.h ../cif/cif.h \
../lef/lefInt.h
+31
View File
@@ -0,0 +1,31 @@
#
# LEF module Makefile
#
MODULE = lef
MAGICDIR = ..
SRCS = lefCmd.c lefTech.c lefWrite.c defWrite.c lefRead.c defRead.c
include ${MAGICDIR}/defs.mak
LIBS += ${LD_EXTRA_LIBS} ${SUB_EXTRA_LIBS}
CLEANS += magiclef${SHDLIB_EXT} tcllef.o
tcl-main: tcllef.o magiclef${SHDLIB_EXT}
tcllef.o: tcllef.c
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} tcllef.c -c -o tcllef.o
magiclef${SHDLIB_EXT}: tcllef.o ${OBJS}
@echo --- making Tcl auto-load module \(magiclef${SHDLIB_EXT}\)
${RM} magiclef${SHDLIB_EXT}
${CC} ${CFLAGS} ${CPPFLAGS} -o $@ ${LDDL_FLAGS} tcllef.o ${OBJS} \
${EXTRA_LIBS} -lc ${LIBS}
install-tcl: $(DESTDIR)${TCLDIR}/magiclef${SHDLIB_EXT}
$(DESTDIR)${TCLDIR}/magiclef${SHDLIB_EXT}: magiclef${SHDLIB_EXT}
${RM} $(DESTDIR)${TCLDIR}/magiclef${SHDLIB_EXT}
${CP} magiclef${SHDLIB_EXT} $(DESTDIR)${TCLDIR}/magiclef${SHDLIB_EXT}
include ${MAGICDIR}/rules.mak
+1439
View File
File diff suppressed because it is too large Load Diff
+1956
View File
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
/*
* lef.h --
*
* Contains definitions for things that are exported by the
* lef module.
*
*/
#ifndef _LEF_H
#define _LEF_H
#include "utils/magic.h"
/* Procedures for reading the technology file: */
extern void LefTechInit();
extern bool LefTechLine();
extern void LefTechScale();
/* Initialization: */
extern void LefInit();
#endif /* _LEF_H */
+220
View File
@@ -0,0 +1,220 @@
/*
* lefCmd.c --
*
* Commands for the LEF module only.
*
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/lef/lefCmd.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "windows/windows.h"
#include "dbwind/dbwind.h"
#include "utils/main.h"
#include "textio/txcommands.h"
#include "commands/commands.h"
/*
* ----------------------------------------------------------------------------
*
* CmdLef --
*
* Implement the "lef" and "def" commands: generate LEF-format output
* for a layout, or read LEF- or DEF-format files.
*
* Usage:
* lef [options]
* def [options]
*
* Results:
* Always return 0.
*
* Side effects:
* Generates LEF-format output on disk somewhere, or reads
* LEF- or DEF-format files, generating cell definitions and
* uses in the process.
*
* ----------------------------------------------------------------------------
*/
/* These definitions must correspond to the ordering in cmdLefOption[] below */
#define LEF_READ 0
#define LEF_WRITE 1
#define LEF_WRITEALL 2
#define LEF_HELP 3
void
CmdLef(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
int option;
char **msg, *namep;
CellUse *selectedUse;
CellDef *selectedDef;
bool is_lef;
bool lefImport = FALSE; /* Indicates whether or not we
* read cells from .mag files
* when the FOREIGN statement
* is encountered in a macro.
*/
bool lefTopCell = TRUE; /* Indicates whether or not we
* write the top-level cell to
* LEF, or just the subcells.
*/
bool allSpecial = FALSE; /* Indicates whether we should
* treat all geometry as "special"
* nets in DEF format output.
*/
static char *cmdLefOption[] =
{
"read [filename] read a LEF file filename[.lef]\n"
" read [filename] -import read a LEF file; import cells from .mag files",
"write [cell] write LEF for current or indicated cell",
"writeall write all cells including the top-level cell\n"
" writeall -notop write all subcells of the top-level cell",
"help print this help information",
NULL
};
static char *cmdDefOption[] =
{
"read [filename] read a DEF file filename[.def]",
"write [cell] [-allspecial] write DEF for current or indicated cell",
"writeall (use \"flatten -nosubckt\" + \"def"
" write\" instead)",
"help print this help information",
NULL
};
/* Determine whether this function has been called via the "lef" or
* the "def" command.
*/
is_lef = (cmd->tx_argv[0][0] == 'd') ? FALSE : TRUE;
if (cmd->tx_argc < 2)
option = LEF_HELP;
else
{
option = Lookup(cmd->tx_argv[1], cmdLefOption);
if (option < 0)
{
TxError("\"%s\" isn't a valid %s option.\n", cmd->tx_argv[1],
cmd->tx_argv[0]);
option = LEF_HELP;
}
}
if (option != LEF_HELP)
{
selectedUse = CmdGetSelectedCell((Transform *)NULL);
if (selectedUse == NULL)
{
windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *) NULL)
{
if (ToolGetBox(&selectedDef,NULL) == FALSE)
{
TxError("Point to a window first\n");
return;
}
selectedUse = selectedDef->cd_parents;
}
else
selectedUse = (CellUse *)w->w_surfaceID;
}
}
switch (option)
{
case LEF_READ:
if (cmd->tx_argc != 3)
{
if (cmd->tx_argc == 4)
{
if (*(cmd->tx_argv[3]) == '-')
if (!strncmp(cmd->tx_argv[3], "-import", 7))
lefImport = TRUE;
}
else
goto wrongNumArgs;
}
namep = cmd->tx_argv[2];
if (is_lef)
LefRead(namep, lefImport);
else
DefRead(namep);
break;
case LEF_WRITEALL:
if (!is_lef)
{
TxError("Sorry, can't write hierarchical DEF at this time.\n");
TxError("Try \"def write\"\n");
}
else
{
if (cmd->tx_argc == 3)
if (*(cmd->tx_argv[2]) == '-')
if (!strncmp(cmd->tx_argv[2], "-notop", 6))
lefTopCell = FALSE;
LefWriteAll(selectedUse, lefTopCell);
}
break;
case LEF_WRITE:
if (!is_lef)
{
allSpecial = FALSE;
if (cmd->tx_argc == 4)
{
if (*(cmd->tx_argv[3]) == '-')
{
if (!strncmp(cmd->tx_argv[3], "-allspec", 8))
allSpecial = TRUE;
else goto wrongNumArgs;
}
else goto wrongNumArgs;
}
else if (cmd->tx_argc != 3) goto wrongNumArgs;
}
else if (cmd->tx_argc != 2) goto wrongNumArgs;
if (selectedUse == NULL)
{
TxError("No cell selected\n");
return;
}
if (cmd->tx_argc == 2)
namep = selectedUse->cu_def->cd_name;
else
namep = cmd->tx_argv[2];
if (!is_lef)
DefWriteCell(selectedUse->cu_def, namep, allSpecial);
else
LefWriteCell(selectedUse->cu_def, namep, selectedUse->cu_def
== EditRootDef);
break;
case LEF_HELP:
wrongNumArgs:
TxPrintf("The \"%s\" options are:\n", cmd->tx_argv[0]);
msg = (is_lef) ? &(cmdLefOption[0]) : &(cmdDefOption[0]);
for (; *msg != NULL; msg++)
{
TxPrintf(" %s %s\n", cmd->tx_argv[0], *msg);
}
break;
}
}
+137
View File
@@ -0,0 +1,137 @@
/*
* lefInt.h --
*
* This file defines things that are used by internal LEF routines in
* various files.
*
* rcsid $Header: /usr/cvsroot/magic-8.0/lef/lefInt.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $
*/
#ifndef _LEFINT_H
#define _LEFINT_H
#include "utils/magic.h"
/* Some constants for LEF and DEF files */
#define LEF_LINE_MAX 2048 /* Maximum length fixed by LEF/DEF specifications */
#define LEF_MAX_ERRORS 100 /* Max # errors to report; limits output if */
/* something is really wrong about the file */
#define DEFAULT_WIDTH 3 /* Default metal width for routes if undefined */
#define DEFAULT_SPACING 4 /* Default spacing between metal if undefined */
/* Structure holding the counts of regular and special nets */
typedef struct
{
int regular;
int special;
bool has_nets;
} NetCount;
/* Various modes for writing nets. */
#define DO_REGULAR 0
#define DO_SPECIAL 1
#define ALL_SPECIAL 2 /* treat all nets as SPECIALNETS */
/* For a linked list of rectangular areas, use the LinkedRect structure */
/* defined in utils/geometry.h. */
/* Structure used for returning information about polygon geometry */
typedef struct _linkedPoint {
Point pos;
TileType type;
struct _linkedPoint *point_next;
} linkedPoint;
/* Structure used to maintain default routing information for each */
/* routable layer type. */
typedef struct {
int width; /* width, in lambda */
int spacing; /* minimum spacing rule, in lambda */
int pitch; /* route pitch, in lambda */
bool hdirection; /* horizontal direction preferred */
} lefRoute;
/* Structure used to maintain default generation information for each */
/* via or viarule (contact) type. If "cell" is non-NULL, then the via */
/* is saved in a cell (pointed to by "cell"), and "area" describes the */
/* bounding box. Otherwise, the via is formed by magic type "type" */
/* with a minimum area "area" for a single contact. */
typedef struct {
Rect area; /* Area of single contact, or cell bbox */
/* in units of 1/2 lambda */
CellDef *cell; /* Cell for fixed via def, or NULL */
LinkedRect *lr; /* Extra information for vias with */
/* more complicated geometry. */
TileType obsType; /* Secondary obstruction type */
} lefVia;
/* Defined types for "lefClass" in the lefLayer structure */
#define CLASS_ROUTE 0 /* routing layer */
#define CLASS_VIA 1 /* via or cut layer */
#define CLASS_MASTER 2 /* masterslice layer */
#define CLASS_OVERLAP 3 /* overlap layer */
#define CLASS_BOUND 4 /* boundary-defining layer */
#define CLASS_IGNORE 5 /* inactive layer */
/* Structure defining a route or via layer and matching it to a magic */
/* layer type. This structure is saved in the LefInfo hash table. */
/* To allow multiple names to refer to the same structure, we keep a */
/* reference count of the number of times a hash table value points to */
/* this structure. */
typedef struct {
TileType type; /* magic tile type, or -1 for none */
TileType obsType; /* magic type to use if this is an obstruction */
short refCnt; /* reference count for memory deallocation */
char * canonName; /* name to use when writing LEF output */
unsigned char lefClass; /* is this a via, route, or masterslice layer */
union {
lefRoute route; /* for route layers */
lefVia via; /* for contacts */
} info;
} lefLayer;
/* Inverse mapping structure for returning the primary LEF */
/* layer corresponding to a magic tile type. */
typedef struct {
char *lefName; /* Primary name of LEF layer */
lefLayer *lefInfo; /* Pointer to information about the layer */
} LefMapping;
/* External declaration of global variables */
extern int lefCurrentLine;
extern HashTable LefInfo;
/* Forward declarations */
int lefDefInitFunc(), lefDefPushFunc();
FILE *lefFileOpen();
char *LefGetInput();
int LefParseEndStatement();
void LefSkipSection();
void LefEndStatement();
CellDef *lefFindCell();
char *LefNextToken();
char *LefLower();
LinkedRect *LefReadGeometry();
void LefEstimate();
lefLayer *LefRedefined();
void LefAddViaGeometry();
Rect *LefReadRect();
TileType LefReadLayer();
LefMapping *defMakeInverseLayerMap();
void LefError(char *, ...); /* Variable argument procedure requires */
/* parameter list. */
#endif /* _LEFINT_H */
+2067
View File
File diff suppressed because it is too large Load Diff
+448
View File
@@ -0,0 +1,448 @@
/*
* lefTech.c --
*
* This module incorporates the LEF/DEF format for standard-cell place and
* route. Defines technology file layer mapping between LEF and magic layer
* types.
*
* Version 0.1 (December 5, 2003): LEF section of the technology file.
* Lets the technology file state how layers declared in the LEF and DEF
* files should correspond to magic layout units. If these are not
* declared, magic will attempt to relate layer names in the LEF file to
* magic layer names and their aliases. The LEF section allows the declaration
* of obstruction layer names, which may be the same as actual layer names in
* the LEF or DEF file, but which should declare a type that takes up space
* on the routing plane but does not connect to any other material. Otherwise,
* some LEF/DEF files will end up merging ports together with the obstruction
* layer.
*
* Layer name case sensitivity should depend on the
* NAMESCASESENSITIVE [ON|OFF] LEF instruction!
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/lef/lefTech.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "utils/malloc.h"
#include "lef/lefInt.h"
#include "drc/drc.h"
/* ---------------------------------------------------------------------*/
/* Layer and Via routing information table. */
HashTable LefInfo;
/*
*-----------------------------------------------------------------------------
* LefInit --
*
* Things that need to be initialized on startup, before the technology
* file is read in.
*
* Results:
* None.
*
* Side effects:
* Hash Table initialization.
*
*-----------------------------------------------------------------------------
*/
void
LefInit()
{
/* Ensure that the table has a null entry so we don't run HashKill */
/* on it when we to the tech initialization. */
LefInfo.ht_table = (HashEntry **) NULL;
}
/*
*-----------------------------------------------------------------------------
* LefTechInit --
*
* Called once at beginning of technology file read-in to initialize
* data structures.
*
* Results:
* None.
*
* Side effects:
* Clears out the LEF layer info table. Because multiple LEF names
* can point to the same record, this is handled by reference count.
* ----------------------------------------------------------------------------
*/
void
LefTechInit()
{
HashSearch hs;
HashEntry *he;
lefLayer *lefl;
if (LefInfo.ht_table != (HashEntry **) NULL)
{
HashStartSearch(&hs);
while (he = HashNext(&LefInfo, &hs))
{
lefl = (lefLayer *)HashGetValue(he);
if (!lefl) continue;
lefl->refCnt--;
if (lefl->refCnt <= 0)
{
/* Via detailed information, if it exists, */
/* needs to have its allocated memory free'd. */
if (lefl->lefClass == CLASS_VIA)
if (lefl->info.via.lr != NULL)
freeMagic(lefl->info.via.lr);
freeMagic(lefl);
}
}
HashKill(&LefInfo);
}
HashInit(&LefInfo, 32, HT_STRINGKEYS);
}
/*
*-----------------------------------------------------------------------------
* lefRemoveGeneratedVias --
*
* Remove the Generated Vias created during a DEF file write
* from the LEF layer hash table. By design, each of these
* generated layers gets a refCnt of zero, so they are easy
* to find.
*
* Results:
* None.
*
* Side effects:
* Memory freed in the hash table.
*
*-----------------------------------------------------------------------------
*/
void
lefRemoveGeneratedVias()
{
HashSearch hs;
HashEntry *he;
lefLayer *lefl;
if (LefInfo.ht_table != (HashEntry **) NULL)
{
HashStartSearch(&hs);
while (he = HashNext(&LefInfo, &hs))
{
lefl = (lefLayer *)HashGetValue(he);
if (!lefl) continue;
if (lefl->refCnt == 0)
{
if (lefl->lefClass == CLASS_VIA)
if (lefl->info.via.lr != NULL)
freeMagic(lefl->info.via.lr);
freeMagic(lefl);
HashSetValue(he, NULL);
}
}
}
}
/*
*-----------------------------------------------------------------------------
* LefTechLine --
*
* This procedure is invoked by the technology module once for
* each line in the "lef" section of the technology file.
*
* Results:
* Always returns TRUE (otherwise the technology module would
* abort Magic with a fatal error).
*
* Side effects:
* Builds up the LEF layer table, prints error messages if necessary.
* ----------------------------------------------------------------------------
*/
#define LEFTECH_OBS 0
#define LEFTECH_LAYER 1
#define LEFTECH_ROUTE 2
#define LEFTECH_ROUTING 3
#define LEFTECH_MASTER 4
#define LEFTECH_CUT 5
#define LEFTECH_CONTACT 6
#define LEFTECH_OVERLAP 7
#define LEFTECH_BOUND 8
#define LEFTECH_IGNORE 9
bool
LefTechLine(sectionName, argc, argv)
char *sectionName; /* Name of this section (unused). */
int argc; /* Number of arguments on line. */
char *argv[]; /* Pointers to fields of line. */
{
bool isObstruction, isContact, isInactive;
HashEntry *he;
TileType mtype, mtype2 = -1;
TileTypeBitMask mmask;
lefLayer *lefl, *newlefl;
int i, option;
static char *keywords[] = {
"obstruction", "layer", "route", "routing", "masterslice",
"cut", "contact", "overlap", "bound", "ignore", NULL
};
option = Lookup(argv[0], keywords);
if (option < 0)
{
TechError("Unknown LEF section keyword: %s. Line ignored.\n", argv[0]);
return TRUE;
}
if ((option != LEFTECH_IGNORE) && (argc < 3))
{
TechError("No LEF layer names present!\n");
return TRUE;
}
isInactive = FALSE;
switch (option)
{
case LEFTECH_IGNORE:
isInactive = TRUE;
break;
case LEFTECH_OBS:
isObstruction = TRUE;
break;
default:
isObstruction = FALSE;
}
TTMaskZero(&mmask);
i = 0;
if (!isInactive)
{
DBTechNoisyNameMask(argv[1], &mmask);
for (mtype2 = TT_TECHDEPBASE; mtype2 < DBNumUserLayers; mtype2++)
{
if (TTMaskHasType(&mmask, mtype2))
{
if (++i == 1)
mtype = mtype2;
else
break;
}
}
if (mtype2 == DBNumUserLayers) mtype2 = -1;
if (i == 0)
{
LefError("Bad magic layer type \"%s\" in LEF layer definition.\n", argv[1]);
return TRUE;
}
else if ((i == 2) && (option != LEFTECH_OBS))
{
LefError("Can only define multiple types for via obstruction layers.\n");
return TRUE;
}
else if (i > 2)
{
LefError("Too many types in LEF layer definition.\n");
return TRUE;
}
isContact = DBIsContact(mtype);
if (option == LEFTECH_LAYER)
option = (isContact) ? LEFTECH_CUT : LEFTECH_ROUTE;
else if (isContact && (option != LEFTECH_CUT && option != LEFTECH_CONTACT))
TechError("Attempt to define cut type %s as %s.\n",
DBTypeLongNameTbl[mtype], keywords[option]);
else if (!isContact && (option == LEFTECH_CUT || option == LEFTECH_CONTACT))
TechError("Attempt to define non-cut type %s as a cut.\n",
DBTypeLongNameTbl[mtype]);
}
/* All other aliases are stuffed in the hash table but point to the */
/* same record as the first. If any name is repeated, then report */
/* an error condition. */
newlefl = NULL;
for (i = 2 - isInactive; i < argc; i++)
{
he = HashFind(&LefInfo, argv[i]);
lefl = (lefLayer *)HashGetValue(he);
if (lefl == NULL)
{
/* Create an entry in the hash table for this layer or obstruction */
if (newlefl == NULL)
{
float oscale = CIFGetOutputScale(1000);
newlefl = (lefLayer *)mallocMagic(sizeof(lefLayer));
newlefl->refCnt = 0;
newlefl->type = -1;
newlefl->obsType = -1;
if (!isInactive)
{
if (isObstruction)
newlefl->obsType = mtype;
else
newlefl->type = mtype;
}
newlefl->canonName = (char *)he->h_key.h_name;
/* Fill in default values per type */
switch (option)
{
case LEFTECH_CUT:
newlefl->lefClass = CLASS_VIA;
newlefl->info.via.area = GeoNullRect;
newlefl->info.via.cell = (CellDef *)NULL;
newlefl->info.via.lr = (LinkedRect *)NULL;
newlefl->info.via.obsType = mtype2;
break;
case LEFTECH_CONTACT:
newlefl->lefClass = CLASS_VIA;
newlefl->info.via.area.r_xtop = DRCGetDefaultLayerWidth(mtype);
newlefl->info.via.area.r_ytop = newlefl->info.via.area.r_xtop;
newlefl->info.via.area.r_xbot = -newlefl->info.via.area.r_xtop;
newlefl->info.via.area.r_ybot = -newlefl->info.via.area.r_ytop;
newlefl->info.via.cell = (CellDef *)NULL;
newlefl->info.via.lr = (LinkedRect *)NULL;
newlefl->info.via.obsType = mtype2;
break;
case LEFTECH_ROUTE:
case LEFTECH_ROUTING:
case LEFTECH_OBS:
newlefl->lefClass = CLASS_ROUTE;
newlefl->info.route.width = DRCGetDefaultLayerWidth(mtype);
if (newlefl->info.route.width == 0)
newlefl->info.route.width = DEFAULT_WIDTH;
newlefl->info.route.spacing =
DRCGetDefaultLayerSpacing(mtype, mtype);
if (newlefl->info.route.spacing == 0)
newlefl->info.route.spacing = DEFAULT_SPACING;
newlefl->info.route.pitch = 0;
newlefl->info.route.hdirection = TRUE;
break;
case LEFTECH_BOUND:
newlefl->lefClass = CLASS_BOUND;
break;
case LEFTECH_MASTER:
newlefl->lefClass = CLASS_MASTER;
break;
case LEFTECH_OVERLAP:
newlefl->lefClass = CLASS_OVERLAP;
break;
case LEFTECH_IGNORE:
newlefl->lefClass = CLASS_IGNORE;
break;
}
}
HashSetValue(he, newlefl);
newlefl->refCnt++;
}
else if (lefl->lefClass != CLASS_IGNORE)
{
if ((lefl->obsType == -1) && isObstruction)
{
// if (DBIsContact(lefl->type) != isContact)
// TechError("Error: Cannot mix layer and via types\n");
// else
{
lefl->obsType = mtype;
if (lefl->lefClass == CLASS_VIA)
lefl->info.via.obsType = mtype2;
}
}
else if ((lefl->type == -1) && !isObstruction)
{
// if (DBIsContact(lefl->obsType) != isContact)
// TechError("Error: Cannot mix layer and via types\n");
// else
lefl->type = mtype;
}
else
TechError("LEF name %s already used for magic type %s\n",
argv[i], DBTypeLongNameTbl[lefl->type]);
}
}
return TRUE;
}
/*
*-----------------------------------------------------------------------------
* LefTechScale --
*
* Change parameters of the LEF section as required when
* redefining magic's internal grid relative to the technology lambda.
*
* ----------------------------------------------------------------------------
*/
void
LefTechScale(scalen, scaled)
int scalen, scaled;
{
HashSearch hs;
HashEntry *he;
lefLayer *lefl;
if (LefInfo.ht_table != (HashEntry **) NULL)
{
HashStartSearch(&hs);
while (he = HashNext(&LefInfo, &hs))
{
lefl = (lefLayer *)HashGetValue(he);
if (!lefl) continue;
if (lefl->refCnt >= 1)
{
/* Avoid scaling more than once. . . */
if (lefl->refCnt > 1) lefl->refCnt = -lefl->refCnt;
if (lefl->lefClass == CLASS_VIA)
{
DBScalePoint(&lefl->info.via.area.r_ll, scaled, scalen);
DBScalePoint(&lefl->info.via.area.r_ur, scaled, scalen);
}
else if (lefl->lefClass == CLASS_ROUTE)
{
lefl->info.route.width *= scaled;
lefl->info.route.width /= scalen;
lefl->info.route.spacing *= scaled;
lefl->info.route.spacing /= scalen;
lefl->info.route.pitch *= scaled;
lefl->info.route.pitch /= scalen;
}
}
}
/* Return all refCnt values to normal */
HashStartSearch(&hs);
while (he = HashNext(&LefInfo, &hs))
{
lefl = (lefLayer *)HashGetValue(he);
if (!lefl) continue;
if (lefl->refCnt < 0)
lefl->refCnt = -lefl->refCnt;
}
}
}
+1062
View File
File diff suppressed because it is too large Load Diff
+63
View File
@@ -0,0 +1,63 @@
/*--------------------------------------------------------------*/
/* tcllef.c */
/* */
/* Allows the "lef" feature to be loaded as a module */
/* under the Tcl/Tk version of magic. Loading is */
/* automatic upon invoking the "lef" command. */
/*--------------------------------------------------------------*/
#ifdef LEF_AUTO
#include <stdio.h>
#include <string.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "windows/windows.h"
#include "commands/commands.h"
#include "utils/tech.h"
#include "dbwind/dbwind.h"
/* External routines */
extern void CmdLef();
/*
* ----------------------------------------------------------------------------
*
* Tcl package initialization function
*
* ----------------------------------------------------------------------------
*/
int
Magiclef_Init(interp)
Tcl_Interp *interp;
{
/* Sanity checks! */
if (interp == NULL) return TCL_ERROR;
if (Tcl_PkgRequire(interp, "Tclmagic", MAGIC_VERSION, 0) == NULL)
return TCL_ERROR;
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) return TCL_ERROR;
TxPrintf("Auto-loading LEF/DEF module\n");
TxFlushOut();
/* Replace the auto-load function with the ones defined in */
/* this package in the command functions list. */
if (WindReplaceCommand(DBWclientID, "lef", CmdLef) < 0)
return TCL_ERROR;
if (WindReplaceCommand(DBWclientID, "def", CmdLef) < 0)
return TCL_ERROR;
Tcl_PkgProvide(interp, "MagicLEF", MAGIC_VERSION);
return TCL_OK;
}
#endif /* LEF_AUTO */